<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/10/31
 * Time: 9:58
 */

namespace app\api\service;


use app\api\model\Order;
use app\api\model\OrderProduct;
use app\api\model\Product;
use app\api\model\UserAddress;
use app\lib\exception\BaseException;
use app\lib\exception\OrderException;
use think\Db;
use think\Exception;

class OrderService
{

    protected $oProducts;
    protected $products;
    protected $uid;

    public function place($uid,$oProducts){
        $this->uid = $uid;
        $this->oProducts  = $oProducts;
        $this->products = $this->getProductsByOrder($this->oProducts);

        $status = $this->getOrderStatus();
        if (!$status['pass']) {
            $status['order_id'] = -1;
            return $status;
        }

        $snap = $this->snapOrder();
        $result = $this->createOrderByTrans($snap);
        $result['pass']=true;
        return $result;


    }

    private function createOrderByTrans($snap){

        Db::startTrans();
        try{
            // = $this->snapOrder();
            $order = new Order();
            $order->order_no = self::makeOrderNo();
            $order->user_id = $this->uid;
            $order->total_price = $snap['orderPrice'];
            $order->total_count = $snap['totalCount'];
            $order->snap_img = $snap['snapImg'];
            $order->snap_name = $snap['snapName'];
            $order->snap_address = $snap['snapAddress'];
            $order->snap_items = json_encode($snap['pStatus']);
            $order->save();
            $order_id = $order->id;
            $time = $order->create_time;

            foreach ($this->oProducts as &$val){
                $val['order_id']=$order_id;
            }
            $orderProduct = new OrderProduct();
            $orderProduct->saveAll($this->oProducts);
            Db::commit();
            return [
                'order_no' => $order->order_no,
                'order_id' => $order_id,
                'create_time' => $time
            ];

        }catch (Exception $e){
            Db::rollback();
            throw $e;
        }
    }

    public function checkOrderStock($orderID){
        $orderProducts = OrderProduct::where('order_id',$orderID)->select();
        $this->products = self::getProductsByOrder($orderProducts);
        $this->oProducts = $orderProducts;

        return $this->getOrderStatus();
    }

    private function snapOrder(){
        $snap = [
            'orderPrice' => 0,
            'totalCount' => 0,
            'pStatus' => [],
            'snapAddress' => json_encode($this->getUserAddress()),
            'snapName' => $this->products[0]['name'],
            'snapImg' => $this->products[0]['main_img_url'],
        ];

        for ($i = 0; $i < count($this->products); $i++) {
            $product = $this->products[$i];
            $oProduct = $this->oProducts[$i];

            $pStatus = $this->snapProduct($product, $oProduct['count']);
            $snap['orderPrice'] += $pStatus['totalPrice'];
            $snap['totalCount'] += $pStatus['counts'];
            array_push($snap['pStatus'], $pStatus);
        }
        return $snap;

    }

    private function snapProduct($product,$oCount){
        $pStatus = [
            'pass' => true,
            'orderPrice' => 0,
            'pStatusArray' => []
        ];

        $pStatus['counts'] = $oCount;
        // 以服务器价格为准，生成订单
        $pStatus['totalPrice'] = $oCount * $product['price'];
        $pStatus['name'] = $product['name'];
        $pStatus['id'] = $product['id'];
        $pStatus['main_img_url'] =$product['main_img_url'];
        $pStatus['price'] = $product['price'];

        return $pStatus;
    }

    private function getUserAddress(){
        $address = UserAddress::where('user_id',$this->uid)->find();
        if(!$address){
            throw new BaseException(
                [
                    'msg' => '用户收货地址不存在，下单失败',
                    'errorCode' => 60001,
                ]);
        }
        return $address;
    }

    public function getOrderStatus(){
        $status = [
            'pass' => true,
            'orderPrice' => 0,
            'pStatusArray' => []
        ];

        foreach ($this->oProducts as $oProduct){
            $pStatus = $this->getProductStatus($oProduct['product_id'],$oProduct['count'],$this->products);
            if(!$pStatus['haveStock']){
                $status['pass']=false;
            }
            $status['orderPrice'] += $pStatus['totalPrice'];
            array_push($status['pStatusArray'],$pStatus);
        }
        return $status;
    }

    private function getProductStatus($oPID, $oCount, $products)
    {
        $pIndex = -1;
        $pStatus = [
            'id' => null,
            'haveStock' => false,
            'count' => 0,
            'name' => '',
            'totalPrice' => 0
        ];

        for($i=0;$i<count($products);$i++){
            if($oPID==$products[$i]['id']){
                $pIndex=$i;
            }
        }

        if($pIndex==-1){
            throw new OrderException(['msg'=>'商品不存在,创建订单失败']);
        }
        $pStatus['id']=$products[$pIndex]['id'];
        $pStatus['count']=$oCount;
        $pStatus['name']=$products[$pIndex]['name'];
        $pStatus['totalPrice'] = $products[$pIndex]['price'] * $oCount;

        if ($products[$pIndex]['stock'] - $oCount >= 0) {
            $pStatus['haveStock'] = true;
        }
        return $pStatus;
    }

    public function getProductsByOrder($oProducts){
        $ids=[];

        foreach ($oProducts as $item){
            $item;
            array_push($ids, $item['product_id']);
        }
        $products = Product::select($ids);

        return $products;
    }

    public static function makeOrderNo()
    {
        $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
        $orderSn =
            $yCode[intval(date('Y')) - 2017] . strtoupper(dechex(date('m'))) . date(
                'd') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf(
                '%02d', rand(0, 99));
        return $orderSn;
    }

}